﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TwitterMatic.Shared.Domain;
using System.Data.Services.Client;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;

namespace TwitterMatic.Shared.Data
{
    public class TimedTweetRepository : TwitterMatic.Shared.Data.ITimedTweetRepository
    {
        protected static readonly string TABLENAME = "TimedTweet";
        protected CloudTableClient cloudTableClient;

        protected TableServiceContext GetDataServiceContext()
        {
            TableServiceContext svc = cloudTableClient.GetDataServiceContext();
            svc.IgnoreMissingProperties = true;

            return svc;
        }

        public TimedTweetRepository(CloudTableClient client)
        {
            cloudTableClient = client;
        }

        public List<TimedTweet> RetrieveAll(string screenName)
        {
            TableServiceContext svc = this.GetDataServiceContext();

            List<TimedTweet> result = svc.CreateQuery<TimedTweet>(TABLENAME).Where(t => t.ScreenName == screenName).ToList();
            foreach (var item in result)
            {
                svc.Detach(item);
            }
            return result;
        }

        public List<TimedTweet> RetrieveDue(DateTime dueDate)
        {
            TableServiceContext svc = this.GetDataServiceContext();

            List<TimedTweet> result = svc.CreateQuery<TimedTweet>(TABLENAME)
                .Where(t => t.SentOn == new DateTime(2000, 01, 01).ToUniversalTime() && t.RetriesLeft > 0 && t.Archived == false && t.SendStatus != "Pending delivery").ToList()
                .Where(t => t.SendOn <= dueDate).ToList();
            foreach (var item in result)
            {
                svc.Detach(item);
            }
            return result;
        }

        public TimedTweet RetrieveById(string screenName, string id)
        {
            TableServiceContext svc = this.GetDataServiceContext();

            if (!string.IsNullOrEmpty(screenName))
            {
                return svc.CreateQuery<TimedTweet>(TABLENAME)
                     .Where(t => t.PartitionKey == screenName && t.RowKey == id)
                     .FirstOrDefault();
            }
            else
            {
                return svc.CreateQuery<TimedTweet>(TABLENAME)
                     .Where(t => t.RowKey == id)
                     .FirstOrDefault();
            }
        }

        public void Insert(string screenName, TimedTweet tweet)
        {
            if (screenName != tweet.ScreenName)
                throw new ArgumentException("screenName");

            TableServiceContext svc = this.GetDataServiceContext();
            svc.AddObject(TABLENAME, tweet);
            svc.SaveChanges();
        }

        public void Update(TimedTweet tweet)
        {
            TableServiceContext svc = this.GetDataServiceContext();

            TimedTweet persistent = svc.CreateQuery<TimedTweet>(TABLENAME).Where(t => t.PartitionKey == tweet.PartitionKey
                && t.RowKey == tweet.RowKey).First();

            persistent.ScreenName = tweet.ScreenName;
            persistent.Status = tweet.Status;
            persistent.SendOn = tweet.SendOn;
            persistent.SentOn = tweet.SentOn;
            persistent.SendStatus = tweet.SendStatus;
            persistent.Archived = tweet.Archived;
            persistent.RetriesLeft = tweet.RetriesLeft;


            svc.UpdateObject(persistent);
            svc.SaveChanges();
        }

        public void Archive(string screenName, TimedTweet tweet)
        {
            if (screenName != tweet.ScreenName)
                throw new ArgumentException("screenName");

            tweet.Archived = true;

            Update(tweet);
        }

        public void Delete(string screenName, TimedTweet tweet)
        {
            if (screenName != tweet.ScreenName)
                throw new ArgumentException("screenName");

            TableServiceContext svc = this.GetDataServiceContext();

            TimedTweet persistent = svc.CreateQuery<TimedTweet>(TABLENAME).Where(t => t.PartitionKey == tweet.PartitionKey
                && t.RowKey == tweet.RowKey).First();

            svc.DeleteObject(persistent);
            svc.SaveChanges();
        }

        public int CountAll()
        {
            TableServiceContext svc = this.GetDataServiceContext();

            DataServiceQuery<TimedTweet> query = svc.CreateQuery<TimedTweet>(TABLENAME);
            return query.ToList().Count();
        }
    }
}